package account

import (
    "errors"

    "github.com/gin-gonic/gin"
    "gorm.io/gorm"
    "iip/account/model"
	"iip/account/account_type"
    "iip/lib"
)



func (s *Account) tryFindRole(c *gin.Context) (*model.Role, error) {

    req_id := &struct {
        ID int64 `uri:"id"`
    }{}
    if err := c.ShouldBindUri(req_id); err == nil {



        var err1 error
        role, err1 := s.GetRoleByID(req_id.ID)
        if err1 != nil {
            s.logger.Error(err1)
            return nil, err1
        }
        return role, nil
    }

    req_name := &struct {
        ID string `uri:"id"`
    }{}
    if err := c.ShouldBindUri(req_name); err == nil {
        var err1 error
        role, err1 := s.GetRoleByName(req_name.ID)
        if err1 != nil {
            s.logger.Error(err1)
            return nil, err1
        }
        return role, nil
    }
    return nil, errors.New("not found")
}


func (s *Account) RoleResourcesSet(c *gin.Context) {

    role, err := s.tryFindRole(c)
    if err != nil {
        s.logger.Error(err)
        lib.JsonError(c, err.Error())
        return
    }


    req_ := &struct {
        ResourceIDList   []int64  `form:"resource_id_list"    json:"resource_id_list"    binding:""`
        ResourceNameList []string `form:"resource_name_list"  json:"resource_name_list"  binding:""`
    }{}
    if err := c.ShouldBindJSON(req_); err != nil {
        lib.JsonError(c, err.Error())
        return
    }
    s.logger.Info("绑定角色资源", req_.ResourceIDList)


    var res_list []*model.Resource
    for _, res_id := range req_.ResourceIDList {
        s.logger.Info("查找", res_id)
        res, err := s.GetResourceByID(res_id)
        if err != nil {
            s.logger.Error(err)
            lib.JsonError(c, err.Error())
            return
        }
        s.logger.Info("找到", res.Name)
        res_list = append(res_list, res)
    }
    for _, res_name := range req_.ResourceNameList {
        s.logger.Info("查找", res_name)
        res, err := s.GetResourceByName(res_name)
        if err != nil {
            s.logger.Error(err)
            lib.JsonError(c, err.Error())
            return
        }
        s.logger.Info("找到", res.Name)
        res_list = append(res_list, res)
    }

    s.logger.Info("共查找到", len(res_list), "个资源")


    err = s.gorm().Transaction(func(tx *gorm.DB) error {

        if err := tx.Where(&model.RoleResource{RoleID: role.ID}).Delete(&model.RoleResource{}).Error; err != nil {
            return err
        }

        for _, res := range res_list {
            rr := &model.RoleResource{}
            rr.ID = s.idgen.NextID()
            rr.RoleID = role.ID
            rr.ResourceID = res.ID
            if err := tx.Create(rr).Error; err != nil {
                return err
            }
        }
        return nil
    })
    if err != nil {
        s.logger.Error(err)
        lib.JsonError(c, err.Error())
        return
    }


    go func() {
        err := s.CasbinUpdate()
        if err != nil {
            s.logger.Error(err.Error())
        }
    }()

    var res_name_lst []string
    for _, res := range res_list {
        res_name_lst = append(res_name_lst, res.Name)
    }
    s.logger.Infof("bind role %s resource done %v", role.Name, res_name_lst)
    lib.JsonData(c, &struct {
        model.Role
        Resource []*model.Resource
    }{
        Role:     *role,
        Resource: res_list,
    })
}


func (s *Account) RoleResourcesGet(c *gin.Context) {

    role, err := s.tryFindRole(c)
    if err != nil {
        s.logger.Error(err)
        lib.JsonError(c, err.Error())
        return
    }


    var res_list []*model.Resource
    if role.Name == account_type.AdminName {

        res_list, err = s.GetAllResources()
        if err != nil {
            s.logger.Error(err)
            lib.JsonError(c, err.Error())
            return
        }
    } else {
        res_list, err = s.GetRoleResources(role.ID)
        if err != nil {
            s.logger.Error(err)
            lib.JsonError(c, err.Error())
            return
        }
    }

    s.logger.Info("query account role resource paged list")
    lib.JsonData(c, &struct {
        Role      model.Role        `json:"role"`
        Resources []*model.Resource `json:"resources"`
    }{
        Role:      *role,
        Resources: res_list,
    })
}
